package com.ideal.gpt.app.local;

import java.io.File;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import com.lzwork.utility.TimeTicker;
import com.lzwork.utility.TimeTicker.TickFormat;
import com.lzwork.utility.collection.IterableWrapper;
import com.lzwork.utility.dictionary.MapDictionary;
import com.lzwork.utility.file.FileUtility;
import com.lzwork.utility.officeparser.ExcelLoader;
import com.lzwork.utility.officeparser.ExcelReader;
import com.lzwork.utility.officeparser.ExcelReader.Line;
import com.lzwork.utility.officeparser.ExcelReader.Page;
import com.lzwork.utility.officeparser.ExcelReader.XlsData;
import com.lzwork.utility.officeparser.ExcelSaver;
import com.lzwork.utility.str.StrUtility;

/**
 * @author LiZheng
 * @date 2023年11月10日 下午5:11:16
 */

public class RenameFiles extends ExcelSaver
{
	int checkNum = 0;
	int renameNum = 0;

	public void rename(File folder, File xlsRecord, boolean recordOnly) throws NoSuchAlgorithmException
	{
		TimeTicker ticker = new TimeTicker();

		Workbook wb = null;
		if (xlsRecord != null)
			wb = createXlsFile(xlsRecord);

		doRename(folder, wb, recordOnly);

		if (wb != null)
		{
			System.out.println("Save record file. Total sheets: " + sheetDic.size());
			saveXlsFile(wb, xlsRecord, true);
		}

		System.out.println("All done. Total " + checkNum + " files checked, " + renameNum + " files renamed. Total cost: "
				+ ticker.tickS(TickFormat.Auto, false));
	}

	Map<String, Sheet> sheetDic = new HashMap<>();

	protected Sheet pickSheet(File source, Workbook wb)
	{
		String folder = source.getParent();

		Sheet sheet = sheetDic.get(folder);

		if (sheet == null)
		{
			Sheet index = sheetDic.get("");
			if (index == null)
			{
				index = wb.createSheet("Index");
				sheetDic.put("", index);
			}
			String name = "Folder" + sheetDic.size();
			appendLine(index, name, folder);

			sheet = wb.createSheet(name);
			sheetDic.put(folder, sheet);
			appendLine(sheet, "Rename", "Origin", "Hash");
			sheet.setColumnWidth(0, 4000);
			sheet.setColumnWidth(1, 4000);
		}

		return sheet;
	}

	protected void doRename(File folder, Workbook wb, boolean recordOnly) throws NoSuchAlgorithmException
	{
		if (folder.isFile())
			return;

		File[] files = folder.listFiles();

		for (File f : files)
		{
			if (f.isDirectory())
				doRename(f, wb, recordOnly);
			else if (f.isFile())
			{
				String name = f.getAbsolutePath();
				name = name.hashCode() + FileUtility.getFileExt(f);

				File dest = FileUtility.getFileSafe(f.getParent(), name);

				if (wb != null)
				{
					Sheet sheet = pickSheet(f, wb);
					String hash = FileUtility.fileContentHash(f);
					appendLine(sheet, name, f.getName(), hash);
				}
				checkNum++;

				if (!recordOnly)
				{
					f.renameTo(dest);
					renameNum++;
					if (renameNum % 1000 == 0)
						System.out.println(renameNum + " files renamed.");
				} else if (checkNum % 1000 == 0)
					System.out.println(checkNum + " files checked.");
			}
		}
	}

	int nameCol = 0;
	int titleCol = 1;
	int hashCol = 2;

	public void writeTitle(File indexFile, File target, Map<String, String> tabLinks)
	{
		MapDictionary<String, String> mapIndex = new MapDictionary<>();

		Map<String, String> mapHash = new HashMap<>();

		XlsData pages = ExcelReader.read(indexFile, tabLinks.values());
		for (Page p : pages)
		{
			Map<String, String> holder = mapIndex.pick(p.getName());
			for (Line l : p.getLines())
			{
				String nowName = l.getDataAt(0);
				String oldName = l.getDataAt(1);
				String hash = l.getDataAt(2);

				holder.put(nowName, oldName);
				mapHash.put(hash, oldName);
			}
		}

		Workbook wb = ExcelLoader.loadWorkBook(target);
		int count = 0;

		for (Sheet sheet : wb)
		{
			String targetName = sheet.getSheetName();
			if (!tabLinks.containsKey(targetName))
			{
				System.out.println("Skip target sheet: " + targetName);
				continue;
			}
			System.out.println("Parsing target sheet: " + targetName);

			String indexName = tabLinks.get(targetName);

			Map<String, String> fileIndex = mapIndex.get(indexName);
			if (fileIndex == null)
			{
				System.out.println("Index [" + indexName + "]not found for sheet: " + targetName);
				continue;
			}

			for (Row row : IterableWrapper.make(sheet.rowIterator()))
			{
				if (row.getRowNum() == 0)
					continue;

				Cell nameC = pickCellAt(row, nameCol);
				Cell titleC = pickCellAt(row, titleCol);

				String file = ExcelLoader.getCellData(nameC).getString();
				if (!StrUtility.stringValid(file))
					continue;

				String title = fileIndex.get(file);

				if (!StrUtility.stringValid(title))
				{
					Cell hashC = pickCellAt(row, hashCol);
					String hash = ExcelLoader.getCellData(hashC).getString();
					title = mapHash.get(hash);
				}

				if (!StrUtility.stringValid(title))
				{
					System.out.println("Missing title for file: " + file + " at " + targetName);
					continue;
				}

				titleC.setCellValue(title);
				count++;

				if (count % 1000 == 0)
					System.out.println(count + " lines checked.");
			}
		}

		File targetOut = FileUtility.renameFileSafe(target, "_title", true);
		saveXlsFile(wb, targetOut);
	}

	@SuppressWarnings("unused")
	public static void main(String[] args)
	{
		File root = new File("V:/12345/input_txt/");

		RenameFiles job = new RenameFiles();
		// job.rename(root, null, false);

		File output = new File("V:/12345/input_txt_raw/nameindex_mega.xlsx");
		// job.rename(root, output, true);

		File target = new File("V:/12345/input_txt_raw/outputmega_T1_N1_S2000.xlsx");

		Map<String, String> links = new HashMap<>();
		links.put("QaParse1", "Folder2");
		links.put("QaParse2", "Folder3");
		links.put("QaParse3", "Folder4");
		links.put("QaParse4", "Folder5");
		job.writeTitle(output, target, links);
	}
}
